package safeCommitter.utils;

import static org.junit.Assert.assertNotNull;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaElement;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IPackageFragment;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.core.JavaModelException;
import org.junit.AfterClass;
import org.junit.BeforeClass;

public class SCTestInitializer {
	protected static TestProject testProject;

	private final static Map<String, IPackageFragment> map = new HashMap<String, IPackageFragment>();

	@BeforeClass
	public static void start() throws CoreException, IOException {
		testProject = new TestProject();
		File baseDir = getSimDir();
		if (baseDir != null) {
			mountProject(baseDir);
		}
		buildProject();
		IJavaProject javaProject = testProject.getJavaProject();
		IProject project = testProject.getProject();
		IFolder folder = project.getFolder(javaProject.getOutputLocation());
		IJavaElement el = javaProject.findElement(new Path("sim.TestStub.class"));
		IResource xml = project.findMember(new Path("src/sim/testNG.xml"));
		assertNotNull(xml);
		assertNotNull(el);
		assertNotNull(folder);
		assertNotNull(javaProject.findType("sim.TestStub"));
	}

	private static void mountProject(final File baseDir) throws CoreException, IOException {
		map.put(baseDir.getName(), testProject.createPackage(baseDir.getName()));
		for (File f : baseDir.listFiles()) {
			if (f.getName().endsWith(".svn")) {
				continue;
			}
			if (f.isDirectory()) {
				mountProject(f);
			} else {
				String file2String = FileUtils.readFileToString(f);
				if (f.getName().endsWith(".java")) {
					testProject.createType(map.get(baseDir.getName()), f.getName(), file2String);
				} else {
					createFile(baseDir.getName(), f.getName(), new FileInputStream(f));

				}
			}
		}

	}

	private static void createFile(final String baseDir, final String name, final FileInputStream source) throws CoreException {
		testProject.createResource(baseDir, name, source);

	}

	protected IMethod getMethod(final String clazzName, final String methodName) throws JavaModelException {
		IJavaProject javaProject = testProject.getJavaProject();
		IType type = javaProject.findType(clazzName);
		return type.getMethod(methodName, null);

	}

	private static File getSimDir() {
		File f = new File("test/sim");
		if (f.exists())
			return f;
		return null;
	}

	private static void buildProject() throws CoreException {
		IProject myProject = testProject.getProject();
		myProject.build(IncrementalProjectBuilder.INCREMENTAL_BUILD, null);

	}

	@AfterClass
	public static void close() throws CoreException {
		testProject.dispose();
	}

	protected IJavaProject getJavaProject() {
		return testProject == null ? null : testProject.getJavaProject();
	}
}
